package org.budo.mongo.wrapper;

import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import org.budo.mongo.filter.MongoFilter;
import org.budo.mongo.filter.MongoFilterChain;
import org.budo.mongo.filter.MongoFilterChainImpl;

import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBObject;
import com.mongodb.ReadPreference;
import com.mongodb.ServerAddress;
import com.mongodb.client.model.Collation;

@SuppressWarnings("deprecation")
public class DBCursorWrapper extends DBCursor {
    private MongoFilterChain filterChain;

    private DBCursor dbCursor;

    public DBCursorWrapper(List<MongoFilter> filters, DBCursor dbCursor, DBCollection collection, DBObject query, DBObject fields, ReadPreference readPreference) {
        super(collection, query, fields, readPreference);
        this.filterChain = new MongoFilterChainImpl(filters);
        this.dbCursor = dbCursor;
    }

    @Override
    public DBCursor addOption(int $0) {
        if (null == this.filterChain) {
            return super.addOption($0);
        } else {
            return filterChain.dbCursor_addOption(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor addSpecial(String $0, Object $1) {
        if (null == this.filterChain) {
            return super.addSpecial($0, $1);
        } else {
            return filterChain.dbCursor_addSpecial(this.dbCursor, $0, $1);
        }
    }

    @Override
    public DBCursor batchSize(int $0) {
        if (null == this.filterChain) {
            return super.batchSize($0);
        } else {
            return filterChain.dbCursor_batchSize(this.dbCursor, $0);
        }
    }

    @Override
    public void close() {
        if (null == this.filterChain) {
            super.close();
        } else {
            filterChain.dbCursor_close(this.dbCursor);
        }
    }

    @Override
    public DBCursor comment(String $0) {
        if (null == this.filterChain) {
            return super.comment($0);
        } else {
            return filterChain.dbCursor_comment(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor copy() {
        if (null == this.filterChain) {
            return super.copy();
        } else {
            return filterChain.dbCursor_copy(this.dbCursor);
        }
    }

    @Override
    public int count() {
        if (null == this.filterChain) {
            return super.count();
        } else {
            return filterChain.dbCursor_count(this.dbCursor);
        }
    }

    @Override
    public DBObject curr() {
        if (null == this.filterChain) {
            return super.curr();
        } else {
            return filterChain.dbCursor_curr(this.dbCursor);
        }
    }

    @Override
    public DBObject explain() {
        if (null == this.filterChain) {
            return super.explain();
        } else {
            return filterChain.dbCursor_explain(this.dbCursor);
        }
    }

    @Override
    public void forEach(Consumer $0) {
        if (null == this.filterChain) {
            super.forEach($0);
        } else {
            filterChain.dbCursor_forEach(this.dbCursor, $0);
        }
    }

    @Override
    public void forEachRemaining(Consumer $0) {
        if (null == this.filterChain) {
            super.forEachRemaining($0);
        } else {
            filterChain.dbCursor_forEachRemaining(this.dbCursor, $0);
        }
    }

    @Override
    public int getBatchSize() {
        if (null == this.filterChain) {
            return super.getBatchSize();
        } else {
            return filterChain.dbCursor_getBatchSize(this.dbCursor);
        }
    }

    @Override
    public Collation getCollation() {
        if (null == this.filterChain) {
            return super.getCollation();
        } else {
            return filterChain.dbCursor_getCollation(this.dbCursor);
        }
    }

    @Override
    public DBCollection getCollection() {
        if (null == this.filterChain) {
            return super.getCollection();
        } else {
            return filterChain.dbCursor_getCollection(this.dbCursor);
        }
    }

    @Override
    public long getCursorId() {
        if (null == this.filterChain) {
            return super.getCursorId();
        } else {
            return filterChain.dbCursor_getCursorId(this.dbCursor);
        }
    }

    @Override
    public DBDecoderFactory getDecoderFactory() {
        if (null == this.filterChain) {
            return super.getDecoderFactory();
        } else {
            return filterChain.dbCursor_getDecoderFactory(this.dbCursor);
        }
    }

    @Override
    public DBObject getKeysWanted() {
        if (null == this.filterChain) {
            return super.getKeysWanted();
        } else {
            return filterChain.dbCursor_getKeysWanted(this.dbCursor);
        }
    }

    @Override
    public int getLimit() {
        if (null == this.filterChain) {
            return super.getLimit();
        } else {
            return filterChain.dbCursor_getLimit(this.dbCursor);
        }
    }

    @Override
    public int getOptions() {
        if (null == this.filterChain) {
            return super.getOptions();
        } else {
            return filterChain.dbCursor_getOptions(this.dbCursor);
        }
    }

    @Override
    public DBObject getQuery() {
        if (null == this.filterChain) {
            return super.getQuery();
        } else {
            return filterChain.dbCursor_getQuery(this.dbCursor);
        }
    }

    @Override
    public ReadPreference getReadPreference() {
        if (null == this.filterChain) {
            return super.getReadPreference();
        } else {
            return filterChain.dbCursor_getReadPreference(this.dbCursor);
        }
    }

    @Override
    public ServerAddress getServerAddress() {
        if (null == this.filterChain) {
            return super.getServerAddress();
        } else {
            return filterChain.dbCursor_getServerAddress(this.dbCursor);
        }
    }

    @Override
    public boolean hasNext() {
        if (null == this.filterChain) {
            return super.hasNext();
        } else {
            return filterChain.dbCursor_hasNext(this.dbCursor);
        }
    }

    @Override
    public DBCursor hint(DBObject $0) {
        if (null == this.filterChain) {
            return super.hint($0);
        } else {
            return filterChain.dbCursor_hint(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor hint(String $0) {
        if (null == this.filterChain) {
            return super.hint($0);
        } else {
            return filterChain.dbCursor_hint(this.dbCursor, $0);
        }
    }

    @Override
    public int itcount() {
        if (null == this.filterChain) {
            return super.itcount();
        } else {
            return filterChain.dbCursor_itcount(this.dbCursor);
        }
    }

    @Override
    public Iterator iterator() {
        if (null == this.filterChain) {
            return super.iterator();
        } else {
            return filterChain.dbCursor_iterator(this.dbCursor);
        }
    }

    @Override
    public int length() {
        if (null == this.filterChain) {
            return super.length();
        } else {
            return filterChain.dbCursor_length(this.dbCursor);
        }
    }

    @Override
    public DBCursor limit(int $0) {
        if (null == this.filterChain) {
            return super.limit($0);
        } else {
            return filterChain.dbCursor_limit(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor max(DBObject $0) {
        if (null == this.filterChain) {
            return super.max($0);
        } else {
            return filterChain.dbCursor_max(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor maxScan(int $0) {
        if (null == this.filterChain) {
            return super.maxScan($0);
        } else {
            return filterChain.dbCursor_maxScan(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor maxTime(long $0, TimeUnit $1) {
        if (null == this.filterChain) {
            return super.maxTime($0, $1);
        } else {
            return filterChain.dbCursor_maxTime(this.dbCursor, $0, $1);
        }
    }

    @Override
    public DBCursor min(DBObject $0) {
        if (null == this.filterChain) {
            return super.min($0);
        } else {
            return filterChain.dbCursor_min(this.dbCursor, $0);
        }
    }

    @Override
    public DBObject next() {
        if (null == this.filterChain) {
            return super.next();
        } else {
            return filterChain.dbCursor_next(this.dbCursor);
        }
    }

    @Override
    public int numSeen() {
        if (null == this.filterChain) {
            return super.numSeen();
        } else {
            return filterChain.dbCursor_numSeen(this.dbCursor);
        }
    }

    @Override
    public DBObject one() {
        if (null == this.filterChain) {
            return super.one();
        } else {
            return filterChain.dbCursor_one(this.dbCursor);
        }
    }

    @Override
    public void remove() {
        if (null == this.filterChain) {
            super.remove();
        } else {
            filterChain.dbCursor_remove(this.dbCursor);
        }
    }

    @Override
    public DBCursor resetOptions() {
        if (null == this.filterChain) {
            return super.resetOptions();
        } else {
            return filterChain.dbCursor_resetOptions(this.dbCursor);
        }
    }

    @Override
    public DBCursor returnKey() {
        if (null == this.filterChain) {
            return super.returnKey();
        } else {
            return filterChain.dbCursor_returnKey(this.dbCursor);
        }
    }

    @Override
    public DBCursor setCollation(Collation $0) {
        if (null == this.filterChain) {
            return super.setCollation($0);
        } else {
            return filterChain.dbCursor_setCollation(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor setDecoderFactory(DBDecoderFactory $0) {
        if (null == this.filterChain) {
            return super.setDecoderFactory($0);
        } else {
            return filterChain.dbCursor_setDecoderFactory(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor setOptions(int $0) {
        if (null == this.filterChain) {
            return super.setOptions($0);
        } else {
            return filterChain.dbCursor_setOptions(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor setReadPreference(ReadPreference $0) {
        if (null == this.filterChain) {
            return super.setReadPreference($0);
        } else {
            return filterChain.dbCursor_setReadPreference(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor showDiskLoc() {
        if (null == this.filterChain) {
            return super.showDiskLoc();
        } else {
            return filterChain.dbCursor_showDiskLoc(this.dbCursor);
        }
    }

    @Override
    public int size() {
        if (null == this.filterChain) {
            return super.size();
        } else {
            return filterChain.dbCursor_size(this.dbCursor);
        }
    }

    @Override
    public DBCursor skip(int $0) {
        if (null == this.filterChain) {
            return super.skip($0);
        } else {
            return filterChain.dbCursor_skip(this.dbCursor, $0);
        }
    }

    @Override
    public DBCursor slaveOk() {
        if (null == this.filterChain) {
            return super.slaveOk();
        } else {
            return filterChain.dbCursor_slaveOk(this.dbCursor);
        }
    }

    @Override
    public DBCursor snapshot() {
        if (null == this.filterChain) {
            return super.snapshot();
        } else {
            return filterChain.dbCursor_snapshot(this.dbCursor);
        }
    }

    @Override
    public DBCursor sort(DBObject $0) {
        if (null == this.filterChain) {
            return super.sort($0);
        } else {
            return filterChain.dbCursor_sort(this.dbCursor, $0);
        }
    }

    @Override
    public Spliterator spliterator() {
        if (null == this.filterChain) {
            return super.spliterator();
        } else {
            return filterChain.dbCursor_spliterator(this.dbCursor);
        }
    }

    @Override
    public List toArray() {
        if (null == this.filterChain) {
            return super.toArray();
        } else {
            return filterChain.dbCursor_toArray(this.dbCursor);
        }
    }

    @Override
    public List toArray(int $0) {
        if (null == this.filterChain) {
            return super.toArray($0);
        } else {
            return filterChain.dbCursor_toArray(this.dbCursor, $0);
        }
    }

    @Override
    public String toString() {
        if (null == this.filterChain) {
            return super.toString();
        } else {
            return filterChain.dbCursor_toString(this.dbCursor);
        }
    }

    @Override
    public DBObject tryNext() {
        if (null == this.filterChain) {
            return super.tryNext();
        } else {
            return filterChain.dbCursor_tryNext(this.dbCursor);
        }
    }

}